<!-- 公共表格组件 -->
<template>
    <div class="table-common">
        <div class="tableList" :class="configFlag.needPage ? 'hasPagination' : ''">
            <el-table v-loading="loading" :ref="tableid" element-loading-text="Loading" border fit highlight-current-row
                :data="tableDatas" :row-key="rowKey" @selection-change="handleSelectionChange"
                @select="selectDataChange" @select-all="selectAllDataChange" :height="tableHeight" :row-style="rowStyle"
                highlight-selection-row :max-height="maxHeight" @row-click="handleRowClick"
                :tooltip-effect="configFlag.tooltip || 'dark'">
                <!-- 当数据为空时，如果想添加一个表达是空数据的图片，可以在这里设置，如果没有就不用管了 -->
                <template slot="empty">
                    <span>/</span>
                </template>
                <!-- 全选单选 -->
                <el-table-column v-if="configFlag.selection" align="center" width="55" type="selection"
                    :reserve-selection="configFlag.reserveSelection" />
                <!-- 序号列 -->
                <el-table-column type="index" v-if="configFlag.index" :label="configFlag.indexName || '序号'"
                    :width="configFlag.indexWidth || 50" align="center" :fixed="configFlag.indexFixed || 'left'">
                    <template slot-scope="scope">
                        <!-- 每页都是从 1 开始 -->
                        {{ scope.$index + 1 }}
                        <!-- 第二页从 11 开始 -->
                        <!-- {{ (pageValue.pageNum - 1) * 10 + (scope.$index + 1) }} -->
                    </template>
                </el-table-column>

                <!-- 循环遍历表头展示数据 -->
                <el-table-column v-for="item in columnsCopy" :key="item.propName" :width="item.width || ''"
                    :min-width="item.minWidth || ''" :prop="item.propName" :label="item.label"
                    :align="item.align || 'center'" :sortable="item.sortable" :fixed="item.fixed || false"
                    header-align="center" :show-overflow-tooltip="item.showOverFlowTooltip"
                    :filters="item.filters ? item.filters : null"
                    :filter-method="item.filters ? item.filtersMethod : null" :selectable="(row) => !row.isSelected">
                    <template slot="header" slot-scope="{ column }">
                        {{ column.label }}
                        <el-tooltip class="item" effect="dark" v-if="item.headertip" :content="item.headertip"
                            placement="top-start">
                            <i class="el-icon-warning"></i>
                        </el-tooltip>
                    </template>
                    <template slot-scope="scope">
                        <!-- {{ scope }} -->
                        <!-- 枚举值 -->
                        <div v-if="item.type == 'statMap'">
                            {{ statMaps(item.options)[scope.row[item.propName]] || "--" }}
                        </div>
                        <!-- 需提示过长信息 -->
                        <div v-else-if="item.showOverFlowTooltip">
                            <div class="show-tooltip">
                                {{ scope.row[item.propName] || "--" }}
                            </div>
                        </div>
                        <!-- 保留两位小数 -->
                        <div v-else-if="item.type == 'tofix2'">
                            {{
                                scope.row[item.propName]
                                    ? Number(scope.row[item.propName]).toFixed(2)
                                    : "--"
                            }}
                        </div>
                        <!-- 金额千分位展示，项目需求，所以暂时就加上了，主要是做个示例，大家可以参考怎么自定义列的一些方法 -->
                        <div v-else-if="item.type == 'money'">
                            <span>{{ getMoneyK(scope.row[item.propName]) || "--" }}</span>
                        </div>
                        <!-- 根据需求添加效果 返回的slot可以优化.自己来吧.可以实现操作列等 -->

                        <slot v-else-if="item.type == undefined && item.slotname" :scope="scope" :field="item.propName"
                            :name="item.slotname"></slot>
                        <!-- 最普通的情况 -->
                        <div v-else>
                            <span>{{ scope.row[item.propName] || "--" }}</span>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <div class="pagination" v-if="configFlag.needPage">
            <el-pagination background :total="pageValue.total" :page-count="pageValue.pageNum"
                :page-size="pageValue.pageSize" :page-sizes="pageSizes" :current-page.sync="pageValue.pageNum"
                :layout="pageValue.pageLayout || pageLayout" @size-change="sizeChange" @current-change="currentChange"
                @prev-click="prevClick" @next-click="nextClick" />
        </div>
    </div>
</template>

<script>
export default {
    name: "Table",
    data() {
        return {
            tableDatas: [],
            loading: true,
            pageLayout: "total,prev, pager, next, jumper",
            columnsCopy: []
        };
    },
    props: {
        // 多选保存选中数据
        rowKey: {
            default: () => (row) => row.index,
        },
        // 为每一行设计样式，比如设置每行的高度等等
        rowStyle: {
            default: () => {
                return { height: "50px" };
            },
        },
        columns: {
            // 表头数据  文案和绑定值，以及需要特殊处理的slot
            type: Array,
            default: () => [],
        },
        tableData: {
            type: Array, // 后台数据
            default: () => [],
        },
        tableid: {
            type: String,
            default: "publicTable",
        },
        // 分页参数
        pageValue: {
            // 分页数据
            type: Object,
            default: () => {
                return {
                    pageNum: 1,
                    pageSize: 20,
                    total: 0,
                    currentPage: 1, //当前页
                };
            },
        },
        // 每页多少条的选项
        pageSizes: {
            type: Array,
            default: () => {
                return [10, 20, 50, 100];
            },
        },
        // 表格配置项
        configFlag: {
            // 配置  其他table配置依次添加
            type: Object,
            default: () => {
                return {
                    needPage: false, // 是否需要分页
                    selection: false, // 是否需要多选
                    index: false, // 是否需要序号
                    indexWidth: 70, //序号列宽
                    btn: false, //序号添加自定义html
                    reserveSelection: false,
                    tooltip: 'dark'
                    // 这里不全面，可根据实际情况添加
                };
            },
        },
        tableHeight: {
            // 可以监听屏幕高度获取。
            // 高度
            // type: Number || String ,
            default: () => '100%',
        },
        maxHeight: {
            // 可以监听屏幕高度获取。
            // 最大高度
            type: Number || String,
            default: () => 900,
        },
        // 是否可以点击行选中多选框
        rowClickSelect: {
            type: Boolean,
            default: true
        }
    },
    watch: {
        tableData: {
            handler: function (newvalue) {
                this.tableDatas = newvalue;
                this.loading = false;
            },
            deep: true,
        },
        columns: {
            handler: function (newvalue) {
                this.columnsCopy = newvalue;
            },
            deep: true,
        }
    },
    beforeUpdate() {
        this.tableDatas = this.$props.tableData;
        this.loading = false;
    },
    computed: {},
    mounted() {
        this.columnsCopy = this.$props.columns;
    },
    methods: {
        // 用于表格中字段是枚举值的列 比如性别 0 代表女 1代表男，就不需要对后台数据单独处理了
        handleRowClick(row) {
            if (this.rowClickSelect) {
                row.isSelected = !row.isSelected;
                this.$refs[this.tableid].toggleRowSelection(row);
            }
        },
        statMaps(list) {
            if (!list) return;
            let obj = {};
            list.forEach((item) => {
                obj[item.value || item.id] = item.label || item.value;
            });
            return obj;
        },
        // 金额千位展示：1,234,567,890
        getMoneyK(money) {
            if (typeof money === "number") {
                money = money.toString();
            }
            var pattern = /(-?\d+)(\d{3})/;
            while (pattern.test(money)) {
                money = money.replace(pattern, "$1,$2");
            }
            return money;
        },
        // 清空选中
        clearSelected() {
            // 父组件通过ref调用clearSelected方法，例如 this.$refs.clearTable.clearSelected()
            this.$refs[this.tableid]?.clearSelection();
        },
        /*
             默认选中
             需要默认选中的在组件中通过this.$refs[tableid].selected(默认选中的数据:Array)
            */
        selected(data) {
            if (data.length > 0) {
                data.forEach((item) => {
                    this.$refs[this.tableid].toggleRowSelection(item, true);
                });
            }
        },
        // 设置条数
        sizeChange(size) {
            this.$emit("sizeChange", size);
        },
        // 翻页，直接跳转
        currentChange(page) {
            this.$emit("handleChange", page);
        },
        //上一页
        prevClick(val) {
            this.$emit("prevClick", val);
        },
        //下一页
        nextClick(val) {
            this.$emit("nextClick", val);
        },
        // 多选
        handleSelectionChange(val) {
            this.$emit("handleSelectionChange", val);
        },
        //点击选中取消选中
        selectDataChange(val, row) {
            this.$emit("selectDataChange", val, row);
        },
        selectAllDataChange(val) {
            this.$emit("selectAllDataChange", val);
        },
        // 多选
        handleSelection(val, row) {
            this.$emit("handleSelection", { val, row });
        },
        handleCellEnter(row, column, cell, event) {
            this.$emit("handleCellEnter", { row, column, cell, event });
        },
        //编辑
        handleEdit(index, row, colIndex, field) {
            this.$emit("handleEdit", { index, row, colIndex, field });
        },
        //下拉框事件
        onSelected(index, row, field) {
            this.$emit("onSelected", { index, row, field });
        },
        //按钮点击事件
        onClickBtn(index, row) {
            this.$emit("onClickBtn", { index, row });
        },
        filterHandler(value, row, column) {
            const property = column["property"];
            return row[property] === value;
        },
        /**重构表格布局 */
        handleResize() {
            this.$nextTick(() => {
                this.$refs[this.tableid].doLayout();
            });
        },
    },
};
</script>
<style lang="scss" scoped>
.table-common {
    width: calc(100% - 30px);
    height: calc(100% - 10px);
    padding: 15px;
    margin: 0 15px;
    margin-bottom: 10px;
    box-sizing: border-box;
    background-color: #ffffff;
    .tableList {
        height: 100%;
    }

    .hasPagination {
        height: calc(100% - 50px);
    }

    .pagination {
        height: 50px;
        display: flex;
        align-items: center;
        justify-content: flex-end;
        background-color: #ffffff;
    }
}
</style>